
#include <BPainter>
#include <BCursor>
#include <BMouseEvent>

#include <BSplitter>
#include "member_BSplitter.h"

using namespace BWE;

#define member					(*(member_BSplitter*)_ptr)
#define member_allocate()		_ptr = new member_BSplitter(this)
#define member_release()		delete (member_BSplitter*)_ptr

BSplitter::BSplitter(BWidget* parent) : BWidget(parent)
{
	member_allocate();
	this->setCursor(Cursor_SizeHor);
}
BSplitter::~BSplitter()
{
	member_release();
}

void BSplitter::setOrientation(Orientation orientation)
{
	if (member.orientation != orientation)
	{
		member.orientation = orientation;
		member.adjust();
		if (orientation == Orientation_Horizontal)
			this->setCursor(Cursor_SizeHor);
		if (orientation == Orientation_Vertical)
			this->setCursor(Cursor_SizeVer);
	}
}
Orientation BSplitter::orientation() const
{
	return member.orientation;
}

void BSplitter::addWidget(BWidget* widget)
{
	if(member.widgets.contain(widget) == false)
	{
		member.widgets.append(widget);
		addChild(widget);
		member.connect(widget, Signal_Show, &member_BSplitter::procShow);
		member.connect(widget, Signal_Hide, &member_BSplitter::procHide);
		member.dirty = true;
	}
}
void BSplitter::insertWidget(int index, BWidget* widget)
{
	if(member.widgets.contain(widget) == false)
	{
		member.widgets.insert(index, widget);
		addChild(widget);
		member.connect(widget, Signal_Show, &member_BSplitter::procShow);
		member.connect(widget, Signal_Hide, &member_BSplitter::procHide);
		member.dirty = true;
	}
}
void BSplitter::removeWidget(BWidget* widget)
{
	member.dirty = member.widgets.remove(widget);
	member.disconnect(widget);
	removeChild(widget);
}

int BSplitter::count() const
{
	return member.widgets.size();
}
BWidget* BSplitter::widget(int index)
{
	return member.widgets[index];
}
const BWidget* BSplitter::widget(int index) const
{
	return member.widgets[index];
}

int BSplitter::indexOf(BWidget* widget)
{
	return member.widgets.indexOf(widget);
}

void BSplitter::setHandle(int handle)
{
	if(member.handle != handle)
	{
		member.handle = handle;
		member.dirty = true;
	}
}
int BSplitter::handle() const
{
	return member.handle;
}

void BSplitter::resizeEvent(const BEvent& event)
{
	member.adjust();
}
void BSplitter::paintEvent(const BEvent& event)
{
	BPainter painter(this);
	painter.drawBackground();
	painter.drawClient();

	BRect handleRect = member.handleRect(member.handleIndex);
	painter.setColor(Color_Hovered);
	painter.fillRect(handleRect);

	painter.drawBorder();
	painter.drawPerch();
	painter.drawMargin();
}

void BSplitter::mouseEnterEvent(const BMouseEvent& mouseEvent)
{
	member.handleIndex = -1;
}
void BSplitter::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{
	if (member.handleIndex != -1)
	{
		member.handleIndex = -1;
		this->fresh();
	}
}

void BSplitter::mousePressEvent(const BMouseEvent& mouseEvent)
{
	if(member.handleIndex >= 0)
	{
		member.holding = true;
		member.pressPos = mouseEvent.pos();
		this->fresh();
	}
}
void BSplitter::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{
	if (member.holding != false)
	{
		member.holding = false;
		this->fresh();
	}
}
void BSplitter::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	if(member.holding)
	{
		member.adjustHandle(mouseEvent.pos());
		member.adjust();
		this->fresh();
	}
	else
	{
		int handleIndex = -1;
		const BPoint& pos = mouseEvent.pos();
		for (int i = 0; i < member.widgets.size() - 1; i++)
		{
			BRect handleRect = member.handleRect(i);
			if (handleRect.contain(pos))
			{
				handleIndex = i;
				break;
			}
		}
		if (member.handleIndex != handleIndex)
		{
			member.handleIndex = handleIndex;
			this->fresh();
		}
	}
}

